﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra.Generic;

namespace innovations.util.collections
{
    public abstract class LimitedCapacityCollection<T> : Collection<T>, ICollection<T>
    {
        public event EventHandler<LimitedCapacityCollectionEventArgs<T>> Changed;

        protected LimitedCapacityCollection() { }

        protected override void InsertItem(int index, T newItem)
        {
            if (IsAtCapacity())
                throw new ArgumentOutOfRangeException("You can't insert an item when capacity has been reached.");
            else
            {
                base.InsertItem(index, newItem);
                EventHandler<LimitedCapacityCollectionEventArgs<T>> temp = Changed;
                if (temp != null)
                {
                    temp(this, new LimitedCapacityCollectionEventArgs<T>(
                        ChangeType.Added, newItem, default(T)));
                }
            }
        }
        

        protected override void SetItem(int index, T newItem)
        {
            T replaced = Items[index];
            base.SetItem(index, newItem);

            EventHandler<LimitedCapacityCollectionEventArgs<T>> temp = Changed;
            if (temp != null)
            {
                temp(this, new LimitedCapacityCollectionEventArgs<T>(
                    ChangeType.Replaced, replaced, newItem));
            }
        }

        protected override void RemoveItem(int index)
        {
            T removedItem = Items[index];
            base.RemoveItem(index);

            EventHandler<LimitedCapacityCollectionEventArgs<T>> temp = Changed;
            if (temp != null)
            {
                temp(this, new LimitedCapacityCollectionEventArgs<T>(
                    ChangeType.Removed, removedItem, default(T)));
            }
        }

        protected override void ClearItems()
        {
            Capacity = 0;
            base.ClearItems();

            EventHandler<LimitedCapacityCollectionEventArgs<T>> temp = Changed;
            if (temp != null)
            {
                temp(this, new LimitedCapacityCollectionEventArgs<T>(
                    ChangeType.Cleared, default(T), default(T)));
            }
        }

        private bool IsAtCapacity()
        {
            if (Capacity <= this.Count)
                return true;
            return false;
        }

        public static int Capacity { get; set;}
    }
}
